<template>
  <div class="api-doc-container">
    <el-card class="api-doc-card" shadow="hover">
      <template #header>
        <div class="card-header">
          <h1>API文档中心</h1>
          <div class="header-actions">
            <el-select v-model="currentVersion" placeholder="选择版本" size="small">
              <el-option v-for="version in versions" :key="version.value" :label="version.label" :value="version.value" />
            </el-select>
            <el-button type="primary" size="small" @click="refreshApiList">刷新</el-button>
          </div>
        </div>
      </template>
      
      <div class="api-doc-content">
        <el-row :gutter="20">
          <!-- 左侧菜单 -->
          <el-col :span="6">
            <div class="api-menu">
              <el-input placeholder="搜索API" v-model="searchKeyword" prefix-icon="Search" clearable />
              
              <el-collapse v-model="activeModules" accordion>
                <el-collapse-item v-for="module in filteredModules" :key="module.id" :title="module.name" :name="module.id">
                  <el-menu :default-active="activeApi" @select="handleSelect">
                    <el-menu-item v-for="api in module.apis" :key="api.id" :index="api.id">
                      <template #title>
                        <el-tag size="small" :type="getMethodType(api.method)">
                          {{ api.method }}
                        </el-tag>
                        <span class="api-path">{{ api.path }}</span>
                      </template>
                    </el-menu-item>
                  </el-menu>
                </el-collapse-item>
              </el-collapse>
            </div>
          </el-col>
          
          <!-- 右侧内容 -->
          <el-col :span="18">
            <div v-if="selectedApi" class="api-detail">
              <div class="api-header">
                <div class="api-title">
                  <el-tag size="medium" :type="getMethodType(selectedApi.method)">{{ selectedApi.method }}</el-tag>
                  <h2>{{ selectedApi.path }}</h2>
                </div>
                <div class="api-status">
                  <el-tag type="success" v-if="selectedApi.status === 'online'">已上线</el-tag>
                  <el-tag type="warning" v-else-if="selectedApi.status === 'debug'">调试中</el-tag>
                  <el-tag type="info" v-else>未知状态</el-tag>
                </div>
              </div>
              
              <div class="api-description">
                <p>{{ selectedApi.description }}</p>
              </div>
              
              <el-divider>请求信息</el-divider>
              
              <!-- 请求参数选项卡 -->
              <el-tabs v-model="requestActiveTab">
                <el-tab-pane label="路径参数" name="path" v-if="selectedApi.pathParams && selectedApi.pathParams.length">
                  <el-table :data="selectedApi.pathParams" stripe border>
                    <el-table-column prop="name" label="参数名" width="180" />
                    <el-table-column prop="type" label="类型" width="120" />
                    <el-table-column prop="required" label="必填" width="80">
                      <template #default="scope">
                        <el-tag :type="scope.row.required ? 'danger' : 'info'" size="small">
                          {{ scope.row.required ? '是' : '否' }}
                        </el-tag>
                      </template>
                    </el-table-column>
                    <el-table-column prop="description" label="说明" />
                    <el-table-column label="测试值" width="180">
                      <template #default="scope">
                        <el-input v-model="requestData.pathParams[scope.row.name]" size="small" placeholder="请输入参数值" />
                      </template>
                    </el-table-column>
                  </el-table>
                </el-tab-pane>
                
                <el-tab-pane label="查询参数" name="query" v-if="selectedApi.queryParams && selectedApi.queryParams.length">
                  <el-table :data="selectedApi.queryParams" stripe border>
                    <el-table-column prop="name" label="参数名" width="180" />
                    <el-table-column prop="type" label="类型" width="120" />
                    <el-table-column prop="required" label="必填" width="80">
                      <template #default="scope">
                        <el-tag :type="scope.row.required ? 'danger' : 'info'" size="small">
                          {{ scope.row.required ? '是' : '否' }}
                        </el-tag>
                      </template>
                    </el-table-column>
                    <el-table-column prop="description" label="说明" />
                    <el-table-column label="测试值" width="180">
                      <template #default="scope">
                        <el-input v-model="requestData.queryParams[scope.row.name]" size="small" placeholder="请输入参数值" />
                      </template>
                    </el-table-column>
                  </el-table>
                </el-tab-pane>
                
                <el-tab-pane label="请求体" name="body" v-if="selectedApi.method !== 'GET' && selectedApi.requestBody">
                  <div class="request-body-type">
                    <el-radio-group v-model="requestBodyType" size="small">
                      <el-radio-button label="form">表单数据</el-radio-button>
                      <el-radio-button label="json">JSON</el-radio-button>
                    </el-radio-group>
                  </div>
                  
                  <div v-if="requestBodyType === 'form' && selectedApi.requestBody.properties">
                    <el-table :data="transformObjectToArray(selectedApi.requestBody.properties)" stripe border>
                      <el-table-column prop="name" label="参数名" width="180" />
                      <el-table-column prop="type" label="类型" width="120" />
                      <el-table-column prop="required" label="必填" width="80">
                        <template #default="scope">
                          <el-tag :type="isRequired(scope.row.name, selectedApi.requestBody.required) ? 'danger' : 'info'" size="small">
                            {{ isRequired(scope.row.name, selectedApi.requestBody.required) ? '是' : '否' }}
                          </el-tag>
                        </template>
                      </el-table-column>
                      <el-table-column prop="description" label="说明" />
                      <el-table-column label="测试值" width="180">
                        <template #default="scope">
                          <el-input v-model="requestData.formData[scope.row.name]" size="small" placeholder="请输入参数值" />
                        </template>
                      </el-table-column>
                    </el-table>
                  </div>
                  
                  <div v-if="requestBodyType === 'json'" class="json-editor">
                    <div class="editor-toolbar">
                      <el-button size="small" @click="formatJson">格式化</el-button>
                      <el-button size="small" @click="clearJson">清空</el-button>
                      <el-button size="small" @click="generateJsonFromSchema">生成示例</el-button>
                    </div>
                    <el-input
                      v-model="requestData.jsonData"
                      type="textarea"
                      :rows="10"
                      placeholder="请输入JSON数据"
                      spellcheck="false"
                    />
                  </div>
                </el-tab-pane>
                
                <el-tab-pane label="请求头" name="header">
                  <el-table :data="defaultHeaders" stripe border>
                    <el-table-column prop="name" label="名称" width="180" />
                    <el-table-column prop="value" label="默认值" width="180" />
                    <el-table-column prop="description" label="说明" />
                    <el-table-column label="操作" width="100">
                      <template #default="scope">
                        <el-switch v-model="scope.row.enabled" active-text="启用" inactive-text="禁用" />
                      </template>
                    </el-table-column>
                  </el-table>
                  
                  <div class="custom-header">
                    <el-divider content-position="left">自定义请求头</el-divider>
                    <div v-for="(header, index) in customHeaders" :key="index" class="custom-header-item">
                      <el-input v-model="header.name" placeholder="请求头名称" />
                      <el-input v-model="header.value" placeholder="请求头值" />
                      <el-button type="danger" circle icon="Delete" @click="removeCustomHeader(index)" />
                    </div>
                    
                    <el-button type="primary" icon="Plus" @click="addCustomHeader">添加请求头</el-button>
                  </div>
                </el-tab-pane>
              </el-tabs>
              
              <div class="api-test">
                <el-divider>测试接口</el-divider>
                <div class="test-url">
                  <div class="url-preview">{{ computedRequestUrl }}</div>
                  <div class="test-actions">
                    <el-button type="primary" :loading="isLoading" @click="sendRequest">发送请求</el-button>
                  </div>
                </div>
              </div>
              
              <!-- 响应结果 -->
              <div v-if="responseData" class="api-response">
                <el-divider>响应结果</el-divider>
                <div class="response-status">
                  <el-tag :type="getStatusType(responseData.status)">状态: {{ responseData.status }}</el-tag>
                  <span class="response-time">请求耗时: {{ responseData.time }}ms</span>
                </div>
                
                <el-tabs v-model="responseActiveTab">
                  <el-tab-pane label="响应体" name="body">
                    <div class="json-viewer">
                      <pre>{{ formattedResponse }}</pre>
                    </div>
                  </el-tab-pane>
                  
                  <el-tab-pane label="响应头" name="headers">
                    <el-table :data="responseHeadersArray" stripe>
                      <el-table-column prop="name" label="名称" width="200" />
                      <el-table-column prop="value" label="值" />
                    </el-table>
                  </el-tab-pane>
                </el-tabs>
              </div>
              
              <!-- 响应例子 -->
              <div class="api-examples">
                <el-divider>响应示例</el-divider>
                <el-tabs v-model="exampleActiveTab">
                  <el-tab-pane label="成功响应" name="success">
                    <div class="json-viewer">
                      <pre>{{ formattedSuccessExample }}</pre>
                    </div>
                  </el-tab-pane>
                  <el-tab-pane label="失败响应" name="error">
                    <div class="json-viewer">
                      <pre>{{ formattedErrorExample }}</pre>
                    </div>
                  </el-tab-pane>
                </el-tabs>
              </div>
            </div>
            
            <div v-else class="api-placeholder">
              <el-empty description="请选择左侧API查看详情">
                <template #image>
                  <el-icon :size="60"><Document /></el-icon>
                </template>
              </el-empty>
            </div>
          </el-col>
        </el-row>
      </div>
    </el-card>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getApiDocList, getApiDocDetail, addApiDoc, updateApiDoc, deleteApiDoc, importApiDoc, exportApiDoc, getApiCategories, updateApiDocStatus, getApiTest } from '@/api/tool/api-doc'

// 搜索表单
const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
  name: '',
  status: ''
})

// 表单数据
const form = reactive({
  docId: undefined,
  name: '',
  description: '',
  url: '',
  method: 'GET',
  contentType: 'application/json',
  content: '',
  status: '1'
})

// 分页信息
const total = ref(0)
const loading = ref(false)
const apiDocList = ref([])
const apiCategories = ref([])

// 弹窗控制
const open = ref(false)
const previewOpen = ref(false)
const testOpen = ref(false)
const importOpen = ref(false)
const title = ref('')
const formRef = ref(null)

// 预览数据
const previewData = ref({})
// 测试数据
const testData = ref({})

// 获取API文档列表
const getList = async () => {
  loading.value = true
  try {
    const res = await getApiDocList(queryParams)
    apiDocList.value = res.data.list
    total.value = res.data.total
  } catch (error) {
    console.error('获取API文档列表失败', error)
  } finally {
    loading.value = false
  }
}

// 获取API分类
const getCategories = async () => {
  try {
    const res = await getApiCategories()
    apiCategories.value = res.data || []
  } catch (error) {
    console.error('获取API分类失败', error)
  }
}

// 重置查询参数
const resetQuery = () => {
  queryParams.name = ''
  queryParams.status = ''
  queryParams.pageNum = 1
  getList()
}

// 处理查询
const handleQuery = () => {
  queryParams.pageNum = 1
  getList()
}

// 处理分页
const handleSizeChange = (size) => {
  queryParams.pageSize = size
  getList()
}

const handleCurrentChange = (current) => {
  queryParams.pageNum = current
  getList()
}

// 重置表单
const resetForm = () => {
  if (formRef.value) {
    formRef.value.resetFields()
  }
  form.docId = undefined
  form.name = ''
  form.description = ''
  form.url = ''
  form.method = 'GET'
  form.contentType = 'application/json'
  form.content = ''
  form.status = '1'
}

// 打开新增弹窗
const handleAdd = () => {
  resetForm()
  open.value = true
  title.value = '新增API文档'
}

// 打开修改弹窗
const handleUpdate = async (row) => {
  resetForm()
  const docId = row.docId
  try {
    const res = await getApiDocDetail(docId)
    Object.assign(form, res.data)
    open.value = true
    title.value = '修改API文档'
  } catch (error) {
    console.error('获取API文档详情失败', error)
  }
}

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return
  
  formRef.value.validate(async (valid) => {
    if (valid) {
      const isUpdate = form.docId !== undefined
      try {
        if (isUpdate) {
          await updateApiDoc(form)
          ElMessage.success('修改成功')
        } else {
          await addApiDoc(form)
          ElMessage.success('新增成功')
        }
        open.value = false
        getList()
      } catch (error) {
        console.error('提交API文档失败', error)
      }
    }
  })
}

// 删除操作
const handleDelete = (row) => {
  const docId = row.docId
  ElMessageBox.confirm('确认删除该API文档吗？', '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      await deleteApiDoc(docId)
      ElMessage.success('删除成功')
      getList()
    } catch (error) {
      console.error('删除API文档失败', error)
    }
  }).catch(() => {})
}

// 更新API状态
const handleStatusChange = async (row) => {
  const docId = row.docId
  const status = row.status === '1' ? '0' : '1'
  try {
    await updateApiDocStatus({ docId, status })
    ElMessage.success(`${status === '1' ? '启用' : '禁用'}成功`)
    getList()
  } catch (error) {
    console.error('更新API状态失败', error)
    // 如果失败，回滚UI状态
    row.status = row.status === '1' ? '0' : '1'
  }
}

// 打开API文档预览
const handlePreview = async (row) => {
  const docId = row.docId
  try {
    const res = await getApiDocDetail(docId)
    previewData.value = res.data
    previewOpen.value = true
  } catch (error) {
    console.error('获取API文档详情失败', error)
  }
}

// 打开API接口测试页面
const handleTest = async (row) => {
  const docId = row.docId
  try {
    const res = await getApiTest(docId)
    testData.value = res.data
    testOpen.value = true
  } catch (error) {
    console.error('获取API接口测试数据失败', error)
  }
}

// 导出API文档
const handleExport = async (row) => {
  const docId = row.docId
  try {
    const res = await exportApiDoc(docId, { format: 'json' })
    const blob = new Blob([res], { type: 'application/json' })
    const link = document.createElement('a')
    link.href = URL.createObjectURL(blob)
    link.download = `api-doc-${docId}.json`
    link.click()
    URL.revokeObjectURL(link.href)
  } catch (error) {
    console.error('导出API文档失败', error)
  }
}

// 打开导入弹窗
const handleImport = () => {
  importOpen.value = true
}

// 导入Swagger文档
const submitImport = async (fileList) => {
  if (!fileList || fileList.length === 0) {
    ElMessage.warning('请选择文件')
    return
  }
  
  const formData = new FormData()
  formData.append('file', fileList[0])
  formData.append('name', importForm.name)
  formData.append('description', importForm.description)
  
  try {
    await importApiDoc(formData)
    ElMessage.success('导入成功')
    importOpen.value = false
    getList()
  } catch (error) {
    console.error('导入Swagger文档失败', error)
  }
}

// 生命周期
onMounted(() => {
  getList()
  getCategories()
})
</script>

<style scoped>
.api-doc-container {
  padding: 20px;
}

.api-doc-card {
  min-height: calc(100vh - 200px);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.api-doc-content {
  margin-top: 20px;
}

.api-menu {
  height: calc(100vh - 300px);
  overflow-y: auto;
  border-right: 1px solid #f0f0f0;
}

.api-menu :deep(.el-menu-item) {
  height: auto;
  line-height: 1.5;
  padding: 10px;
}

.api-menu :deep(.el-menu-item.is-active) {
  background-color: #ecf5ff;
}

.api-path {
  margin-left: 10px;
  word-break: break-all;
}

.api-detail {
  padding: 0 20px;
}

.api-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.api-title {
  display: flex;
  align-items: center;
}

.api-title h2 {
  margin: 0 0 0 10px;
  font-weight: 500;
  word-break: break-all;
}

.api-description {
  color: #666;
  margin-bottom: 20px;
}

.request-body-type {
  margin-bottom: 20px;
}

.json-editor {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  overflow: hidden;
}

.editor-toolbar {
  padding: 8px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #dcdfe6;
  display: flex;
  gap: 10px;
}

.custom-header {
  margin-top: 20px;
}

.custom-header-item {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.test-url {
  display: flex;
  margin-bottom: 20px;
  align-items: center;
}

.url-preview {
  flex: 1;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
  word-break: break-all;
  font-family: monospace;
}

.test-actions {
  margin-left: 10px;
}

.api-response {
  margin-top: 30px;
}

.response-status {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
}

.response-time {
  margin-left: 10px;
  color: #666;
}

.json-viewer {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px;
  background-color: #f5f7fa;
  overflow-x: auto;
}

.json-viewer pre {
  font-family: monospace;
  margin: 0;
  white-space: pre-wrap;
}

.api-placeholder {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 50px;
}
</style> 